﻿using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using System;
using System.Linq;

namespace CUDLR
{
    /// <summary>
    /// 文件处理帮助类
    /// </summary>
    public class FileManager
    {
        /// <summary> 根目录 文件夹名字</summary>
        public const string ROOT_NAME = "files";
        /// <summary> 根目录 </summary>
        public static readonly string ROOT_PATH = string.Format("{0}/CUDLR/{1}/", Application.streamingAssetsPath, ROOT_NAME);
        /// <summary> 资源根目录 </summary>
        public static readonly string RES_ROOT_PATH = string.Format("{0}/res/", ROOT_PATH);
        /// <summary> 命令处理列表 </summary>
        static Dictionary<string, Action<RequestContext>> fileCmdDic;
        /// <summary> 文件路径映射表  </summary>
        static Dictionary<string, string> filePathDic;
        /// <summary> 文件后缀  图标资源映射</summary>
        static Dictionary<string, string> fileIconNameDic;

        static FileManager()
        {
            fileCmdDic = new Dictionary<string, Action<RequestContext>>();
            fileCmdDic["list_root"] = ListRoot;
            fileCmdDic["list"] = ListDir;
            fileCmdDic["ext_icon"] = GetIcon;
            fileCmdDic["file"] = GetFile;
            fileCmdDic["delete"] = DelFile;

            filePathDic = new Dictionary<string, string>();
            filePathDic["dataPath"] = Application.dataPath;
            filePathDic["persistentDataPath"] = Application.persistentDataPath;
            filePathDic["streamingAssetsPath"] = Application.streamingAssetsPath;
            filePathDic["temporaryCachePath"] = Application.temporaryCachePath;

            fileIconNameDic = new Dictionary<string, string>();
            fileIconNameDic["txt"] = "icon_text_view.png";
            fileIconNameDic["xml"] = "icon_text_view.png";
            fileIconNameDic["json"] = "icon_text_view.png";
            fileIconNameDic["log"] = "icon_text_view.png";
            fileIconNameDic["js"] = "icon_text_view.png";
            fileIconNameDic["mp3"] = "icon_music.png";
            fileIconNameDic["mp4"] = "icon_video.png";
            fileIconNameDic["rmvb"] = "icon_video.png";
            fileIconNameDic["mkv"] = "icon_video.png";
            fileIconNameDic["pdf"] = "icon_pdf_view.png";
            fileIconNameDic["png"] = "icon_img_view.png";
            fileIconNameDic["jpg"] = "icon_img_view.png";
            fileIconNameDic["jpeg"] = "icon_img_view.png";
            fileIconNameDic["apk"] = "le_apps.png";
        }

        /// 处理前端文件管理器 传来的命令
        /// 路由规则： ROOT目录下，非文件类型， 就解析为命令
        /// </summary>
        /// <param name="context"></param>
        [Route(@"^/" + ROOT_NAME, @"(GET|HEAD|DELETE)"), ]
        public static void ProcessFileManagerCmd(RequestContext context)
        {
            string cmd = context.Request.QueryString.Get("cmd");
            string result = string.Empty;
            Action<RequestContext> handler = null;
            if (!string.IsNullOrEmpty(cmd) && fileCmdDic.TryGetValue(cmd, out handler))
            {
                if (handler != null) handler(context);
            }
            else
            {
                UseDefaultHandle(context);
            }
        }

        /// <summary>
        /// 使用默认的请求处理
        /// </summary>
        /// <param name="context"></param>
        static private void UseDefaultHandle(RequestContext context)
        {
            if (context == null) return;
            context.currentRoute++; //跳转到下一个路由 处理
            Server.HandleRequest(context);
        }

        /// <summary>
        /// 列出根目录
        /// </summary>
        /// <param name="context"></param>
        private static void ListRoot(RequestContext context)
        {
            string result = String.Empty;
            var obj = new ListRoot()
            {
                hasDon = true,
                device_name = SystemInfo.deviceName,
                device_uuid = SystemInfo.deviceUniqueIdentifier,
            };
            obj.files = new RootItem[filePathDic.Count];
            var i = 0;
            foreach(var kv in filePathDic)
            {
                obj.files[i] = new RootItem()
                {
                    n = kv.Key,
                    has_children = true,
                    t = EDirType.Driver,
                    mount = kv.Key,
                };
                i++;
            }
            result = JsonUtility.ToJson(obj);
            context.context.Response.WriteString(result);
        }

        /// <summary>
        /// 列出文件
        /// </summary>
        /// <param name="context"></param>
        private static void ListDir(RequestContext context)
        {
            var result = new ListFile()
            {
                hasDon = true,
            };

            var path = GetFileRealPath(context.path);
            var parentDir = new DirectoryInfo(path);
            var files = parentDir.GetFiles();
            var dirs = parentDir.GetDirectories();
            result.files = new FileItem[files.Length + dirs.Length];
            var index = 0;
            foreach (var dir in dirs)
            {
                result.files[index] = new FileItem()
                {
                    n = dir.Name,
                    has_children = dir.GetFiles().Length > 0,
                    t = EDirType.Floder,
                };
                index++;
            }

            foreach (var file in files)
            {
                result.files[index] = new FileItem()
                {
                    n = file.Name,
                    size = file.Length,
                    time = ToUnixTimeStamp(file.CreationTime),
                    t = EDirType.File,
                };
                index++;
            }

            var json = JsonUtility.ToJson(result);
            context.context.Response.WriteString(json);
        }

        /// <summary>
        /// 获取文件图标
        /// </summary>
        /// <param name="context"></param>
        private static void GetIcon(RequestContext context)
        {
            var suffix = context.Request.QueryString.Get("suffix");
            if (!string.IsNullOrEmpty(suffix))
            {
                string iconName = null;
                if(!fileIconNameDic.TryGetValue(suffix, out iconName))
                {
                    iconName = "le_unknown.png"; //没有配置， 给默认图标
                }
                context.path = string.Format("/{0}/res/{1}", ROOT_NAME, iconName);
                UseDefaultHandle(context);
            }
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="context"></param>
        private static void GetFile(RequestContext context)
        {
            var path = GetFileRealPath(context.path);
            context.Response.WriteFile(path);
        }

        private static void DelFile(RequestContext context)
        {
            var path = GetFileRealPath(context.path);
            File.Delete(path);
            var result = new DeleteFile()
            {
                ok = !File.Exists(path),
            };
            context.Response.WriteString(JsonUtility.ToJson(result));
        }

        /// <summary>
        /// 列出Android assets 下目录
        /// </summary>
        private static void ListAndroidAssetFile()
        {
            var javaClass = new AndroidJavaClass("xyz.zxin.asset_helper.AssetHelper");
            if(javaClass == null)
            {
                Debug.LogError("java class == null");
                return;
            }
            var unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
            var currentActivity = unityClass.GetStatic<AndroidJavaObject>("currentActivity");
            javaClass.CallStatic("Init", currentActivity);
            var dirsInfo = javaClass.CallStatic<string>("ListDir", "");
            Debug.LogError(dirsInfo);
        }

        /// <summary>
        /// 获取文件真实路径   路径映射
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        private static string GetFileRealPath(string path)
        {
            var idx = path.IndexOf(ROOT_NAME);
            if (idx == -1)
                return path;
            var result = path.Substring(idx + ROOT_NAME.Length + 1);
            foreach (var kv in filePathDic)
            {
                idx = result.IndexOf(kv.Key);
                if (idx != -1)
                {
                    return kv.Value + "/" + result.Substring(idx + kv.Key.Length);
                }
            }
            return result;
        }


        /// <summary>
        /// DateTime 转化为 Unix 毫秒时间戳
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        static long ToUnixTimeStamp(DateTime time)
        {
            var startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            long timeStamp = (long)(time - startTime).TotalMilliseconds;
            return timeStamp;
        }
    }

}
